#!/usr/bin/env python3
# -*- coding: utf-8 -*-
# @Time    : 2019/7/4 11:49 AM
# @Author  : w8ay

import random
import re

from api import VulType
from lib.core.common import md5, generateResponse
from lib.core.data import conf, KB
from lib.core.enums import WEB_PLATFORM
from lib.core.plugins import PluginBase
from lib.helper.helper_sensitive import sensitive_page_error_message_check


class Z0SCAN(PluginBase):
    name = 'PHP代码注入'
    desc = '''PHP代码注入发现，可执行任意php代码'''

    def audit(self):
        if WEB_PLATFORM.PHP not in self.response.programing:
            return
        if conf.level >= 3 and not KB["WafState"]:
            regx = 'Parse error: syntax error,.*?\sin\s'
            randint = random.randint(5120, 10240)
            verify_result = md5(str(randint).encode())
            _payloads = [
                "print(md5({}));".format(randint),
                ";print(md5({}));".format(randint),
                "';print(md5({}));$a='".format(randint),
                "\";print(md5({}));$a=\"".format(randint),
                "${{@print(md5({}))}}".format(randint),
                "${{@print(md5({}))}}\\".format(randint),
                "'.print(md5({})).'".format(randint)
            ]
            # 载入处理位置以及原始payload
            iterdatas = self.generateItemdatas()

            errors = None
            errors_raw = ()
            # 根据原始payload和位置组合新的payload
            for origin_dict, positon in iterdatas:
                payloads = self.paramsCombination(origin_dict, positon, _payloads)
                for key, value, new_value, payload in payloads:
                    r = self.req(positon, payload)
                    if not r:
                        continue
                    html1 = r.text
                    if verify_result in html1:
                        result = self.new_result()
                        result.init_info(self.requests.url, self.desc, VulType.CMD_INNJECTION)
                        result.add_detail("payload探测", r.reqinfo, generateResponse(r),
                                        "探测payload:{}并发现回显:{}".format(new_value, verify_result), key, value, positon)
                        self.success(result)
                        break
                    if re.search(regx, html1, re.I | re.S | re.M):
                        result = self.new_result()
                        result.init_info(self.requests.url, self.desc, VulType.CMD_INNJECTION)
                        result.add_detail("payload探测", r.reqinfo, generateResponse(r),
                                        "探测payload:{}并发现正则回显:{},可能是payload未闭合语句造成的错误".format(new_value, regx), key,
                                        value, positon)
                        self.success(result)
                        break
                    if not errors:
                        errors = sensitive_page_error_message_check(html1)
                        if errors:
                            errors_raw = (key, value)

                if errors:
                    result = self.new_result()
                    key, value = errors_raw
                    result.init_info(self.requests.url, "敏感配置信息泄漏", VulType.SENSITIVE)
                    for m in errors:
                        text = m["text"]
                        _type = m["type"]
                        result.add_detail("payload请求", r.reqinfo, generateResponse(r),
                                        "匹配组件:{} 匹配正则:{}".format(_type, text), key, value, positon)
                    self.success(result)
